Delay block hydration to allow interactive block stores to initialize #66772
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #66691.
When
scheduler.yield()
is available, thesplitTask()
function is implemented to use it. When a task is split withscheduler.yield()
it results in the tail being added to the front of the task queue. In contrast, whensplitTask()
is implemented withsetTimeout()
(whenscheduler.yield()
is not available), then the tail of the split task is added to the end of the task queue. It appears there is a race condition between the call toinit
.In particular, given this
init
function:gutenberg/packages/interactivity/src/init.ts
Lines 30 to 46 in 7f49b39
It is getting invoked before the code in a block's
view.js
is invoked, for example:gutenberg/packages/block-library/src/image/view.js
Line 22 in 7f49b39
When
splitTask()
is was usingsetTimeout()
then the calls toawait splitTask()
had the effect of delaying the hydration until after the blocks' view modules execute. But whensplitTask()
is implemented withscheduler.yield()
the hydration logic is executing before the interactive blocks' view module (i.e. the store initialization) executes.Of note, the error also occurs if
await splitTask()
is eliminated frominit
function as well, indicating that it was not correctly accounting for delaying the Interactivity API'sinit
until after the interactive blocks have all initialized. There seems to be a dependency problem here, where hydration of an interactive block should be blocked until its corresponding view script module has loaded. This seems to be related to:In the mean time, adding a
setTimeout()
to handle the delay seems to do the trick.Code execution with
splitTask
implemented withsetTimeout
gutenberg/packages/interactivity/src/init.ts
Lines 31 to 38 in 7f49b39
gutenberg/packages/block-library/src/image/view.js
Line 22 in 7f49b39
gutenberg/packages/interactivity/src/init.ts
Lines 39 to 46 in 7f49b39
Code execution with
splitTask
implemented withscheduler.yield
gutenberg/packages/interactivity/src/init.ts
Lines 30 to 46 in 7f49b39
gutenberg/packages/block-library/src/image/view.js
Line 22 in 7f49b39